﻿using Action = Styx.TreeSharp.Action;
using Styx;
using Styx;
using Styx.Helpers;
using Styx.Pathing;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.CommonBot.POI;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Diagnostics;
using System.Threading;
using System.Windows.Media;


namespace Spriest
{
    public partial class Classname : CombatRoutine
    {
        public static Stopwatch MoveBackTimer = new Stopwatch();
        public static Stopwatch MindFlayTimer = new Stopwatch();
        public static Stopwatch dotTimer = new Stopwatch();


        public int AngelicFeather = 121536;
        public int ArcaneTorrent = 28730;
        public int BindingHeal = 32546;
        public int Cascade = 127632;
        public int DesperatePrayer = 19236;
        public int DevouringPlague = 2944;
        public int DispelMagic = 528;
        public int Dispersion = 47585;
        public int DivineStar = 110744;
        public int DominateMind = 605;
        public int Fade = 586;
        public int FearWard = 6346;
        public int FlashHeal = 2061;
        public int FromDarknessComesLight = 109186;
        public int GiftOfTheNaruu = 59544;
        public int Halo = 120517;
        public int HymnOfHope = 64901;
        public int InnerFire = 588;
        public int InnerWill = 73413;
        public int LeapOfFaith = 73325;
        public int Levitate = 1706;
        public int Lifeblood = 74497;
        public int MassDispel = 32375;
        public int MindBlast = 8092;
        public int MindBinder = 123040;
        public int MindFlay = 15407;
        public int MindSear = 48045;
        public int MindSpike = 73510;
        public int MindVision = 2096;
        public int PowerWordFortitude = 21562;
        public int PowerInfusion = 10060;
        public int PowerWordShield = 17;
        public int PrayerOfMending = 33076;
        public int PsyFiend = 108921;
        public int PsychicHorror = 64044;
        public int PsychicScream = 8122;
        public int Renew = 139;
        public int Resurrection = 2006;
        public int ShackleUndead = 9484;
        public int ShadowWordDeath = 32379;
        public int ShadowWordPain = 589;
        public int ShadowFiend = 34433;
        public int ShadowForm = 15473;
        public int Silence = 15487;
        public int Smite = 585;
        public int SpectralGuise = 112833;
        public int SurgeOfDarkness = 87160;
        public int VampiricEmbrace = 15286;
        public int VampiricTouch = 34914;
        public int VoidShift = 108968;
        public int VoidTendrils = 108920;
        public int DivineInsight = 109175;
        public int SolaceAndInsanity = 139139;

        public string HavePotionBuff = "";
        public string HaveFlaskBuff = "";
        public string HaveHealPotions = "";
        public string HaveLifeSpirit = "";
        public string HaveHealthStone = "";
        public string LastSpell = "";
        public string HaveFlasks = "";
        public int LastSpellID = 0;


        #region usespells or not
        public bool UseSpells
        {
            get
            {
                if (Me.Mounted
                    || Me.IsGhost
                    || Me.IsDead
                    || Me.IsOnTransport)
                {
                    return false;
                }
                return true;
            }
        }
        #endregion usespells or not

        #region AddCounting
        private int addCount
        {
            get
            {
                int count = 0;
                foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
                {
                    if (u.IsAlive
                        && u.CanSelect
                        && u.Guid != Me.Guid
                        && !u.IsFriendly
                        && u.IsHostile
                        && u.Attackable
                        && !u.IsTotem
                        && !u.IsCritter
                        && !u.IsNonCombatPet
                        && (u.Location.Distance(Me.CurrentTarget.Location) <= 10 || u.Location.Distance2D(Me.CurrentTarget.Location) <= 10))
                    {
                        count++;
                    }
                }
                return count;
            }
        }
        #endregion addcount

        #region Movement
        public void MoveInRange(float dist)
        {
            if (gotTarget)
            {
                float range = dist;
                while (Me.CurrentTarget != null
                    && StyxWoW.Me.Location.Distance(StyxWoW.Me.CurrentTarget.Location) > range)
                {
                    Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
                };
                Navigator.PlayerMover.MoveStop();
            }

        }
        public void MoveBack(WoWMovement.MovementDirection direction)
        {
            MoveBackTimer.Start();

            while (MoveBackTimer.Elapsed.Seconds != 1)
            {
                WoWMovement.Move(direction);
            }

            Navigator.PlayerMover.MoveStop();
            MoveBackTimer.Reset();
        }
        public void MoveInLignOfSight()
        {
            while (!Me.CurrentTarget.InLineOfSight)
            {
                Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
            }
            Navigator.PlayerMover.MoveStop();
        }
        #endregion Movement

        #region facing
        public void Facing()
        {
            if (gotTarget)
            {
                Me.CurrentTarget.Face();
            }
        }
        #endregion facing

        #region Kind of target
        public bool IsBoss
        {
            get
            {
                if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.WorldBoss)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && target.IsBoss(Me.CurrentTarget))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.MaxHealth >= (65 * 1000000))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * SpriestSettings.myPrefs.ElitesHealth)
                    && !Me.GroupInfo.IsInParty
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.Name.Contains("Training Dummy"))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsPlayer
                    && !Me.CurrentTarget.IsFriendly)
                {
                    return true;
                }
                return false;
            }
        }

        #endregion Kind of Target

        #region targettest
        public static void EnsureTarget()
        {
            GatherTarget2();
        }
        public static WoWObject GatherTarget2()
        {

            // Check bot poi.
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var unit = BotPoi.Current.AsObject as WoWUnit;

                if (unit != null 
                    && unit.IsAlive 
                    && !unit.IsMe 
                    && !Blacklist.Contains(unit))
                {
                    return unit;
                }
            }

            // Does the target list have anything in it? And is the unit in combat?
            // Make sure we only check target combat, if we're NOT in a BG. (Inside BGs, all targets are valid!!)
            var firstUnit = Targeting.Instance.FirstUnit;
            if (firstUnit != null 
                && firstUnit.IsAlive 
                && !firstUnit.IsMe 
                && firstUnit.Combat 
                && !Blacklist.Contains(firstUnit))
            {
                return firstUnit;
            }

            // Cache this query, since we'll be using it for 2 checks. No need to re-query it.
            var agroMob =
                ObjectManager.GetObjectsOfType<WoWUnit>(false, false).
                    Where(p => !Blacklist.Contains(p) 
                        && p.IsHostile 
                        && !p.IsOnTransport 
                        && !p.IsDead 
                        && !p.Mounted 
                        && p.DistanceSqr <= 70 * 70 
                        && p.Combat).
                    OrderBy(u => u.DistanceSqr).
                    FirstOrDefault();

            if (agroMob != null)
            {
                // Return the closest one to us
                return agroMob;
            }

            // And there's nothing left, so just return null, kthx.
            return null;
        }
        #endregion target

        #region Trinkets
        public void UseTrinket1()
        {
            if (Me.CurrentTarget != null
                && Me.CurrentTarget.IsAlive
                && Me.Combat)
            {

                var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;
                if (SpriestSettings.myPrefs.trinket1 == 1
                    && IsBoss)
                {

                    if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                    {
                        firstTrinket.Use();
                        LogMsg("Using 1st trinket", 2);
                        return;
                    }
                }
                if (SpriestSettings.myPrefs.trinket1 == 2)
                {
                    if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                    {
                        firstTrinket.Use();
                        LogMsg("Using 1st trinket", 2);
                        return;
                    }
                }
            }
            return;
        }
        public void UseTrinket2()
        {

            if (Me.CurrentTarget != null
                && Me.CurrentTarget.IsAlive
                && Me.Combat)
            {
                var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;


                if (SpriestSettings.myPrefs.trinket2 == 1
                    && IsBoss)
                {

                    if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                    {
                        secondTrinket.Use();
                        LogMsg("Using 2nd trinket", 2);
                        return;
                    }
                }
                if (SpriestSettings.myPrefs.trinket2 == 2)
                {
                    if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                    {
                        secondTrinket.Use();
                        LogMsg("Using 2nd trinket", 2);
                        return;
                    }
                }
            }
            return;
        }
        public void UseEngiGloves()
        {

            if (Me.CurrentTarget != null
                && Me.CurrentTarget.IsAlive
                && Me.Combat)
            {
                var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                if (SpriestSettings.myPrefs.engigloves == 1
                    && IsBoss)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                        return;
                    }
                }
                else if (SpriestSettings.myPrefs.engigloves == 2)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                        return;
                    }
                }
            }
            return;
        }
        public void UseEngiBelt()
        {

            if (gotTarget
                && Me.Combat
                && Me.HealthPercent <= SpriestSettings.myPrefs.engibeltpercent)
            {
                var engiBelt = StyxWoW.Me.Inventory.Equipped.Waist;

                 
                    if (engiBelt != null && CanUseEquippedItem(engiBelt))
                    {
                        engiBelt.Use();
                        LogMsg("Using Engineer Belt", 2);
                        return;
                    }
            }
            return;
        }
        private static bool CanUseEquippedItem(WoWItem item)
        {
            // Check for engineering tinkers!
            string itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0);
            if (string.IsNullOrEmpty(itemSpell))
                return false;


            return item.Usable && item.Cooldown <= 0;
        }
        #endregion Trinkets

        #region logs
        public void LogMsg(string msg, int kleurtje)
        {
            Color kleur = Colors.Yellow;
            switch (kleurtje)
            {
                case 0:
                    kleur = Colors.Orange;
                    break;
                case 1:
                    kleur = Colors.PaleGreen;
                    break;
                case 2:
                    kleur = Colors.BlanchedAlmond;
                    break;
                case 3:
                    kleur = Colors.Yellow;
                    break;
                case 4:
                    kleur = Colors.Red;
                    break;
                case 5:
                    kleur = Colors.Crimson;
                    break;
                case 6:
                    kleur = Colors.LightBlue;
                    break;
                case 7:
                    kleur = Colors.Cyan;
                    break;
                case 8:
                    kleur = Colors.DarkSeaGreen; // TotH
                    break;
                case 9:
                    kleur = Colors.ForestGreen; //Lock and load
                    break;
                case 10:
                    kleur = Colors.DeepSkyBlue; //focusdump
                    break;
            }
            Logging.Write(kleur, msg);
            LastSpell = msg;
        }
        #endregion logs

        #region Methods

        #region Buff Checks

        public bool buffExists(int Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraById(Buff);
                if (Results != null)
                    return true;
            }
            return false;
        }
        public bool buffExists(string Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraByName(Buff);
                if (Results != null)
                    return true;
            }
            return false;
        }
        public double buffTimeLeft(int Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraById(Buff);
                if (Results != null)
                {
                    if (Results.TimeLeft.TotalMilliseconds > 0)
                        return Results.TimeLeft.TotalMilliseconds;
                }
            }
            return 0;
        }

        public uint buffStackCount(int Buff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.GetAuraById(Buff);
                if (Results != null)
                    return Results.StackCount;
            }
            return 0;
        }
        #endregion

        #region Cache Checks
        public IEnumerable<WoWAura> cachedAuras = new List<WoWAura>();
        public IEnumerable<WoWAura> cachedTargetAuras = new List<WoWAura>();
        public void getCachedAuras()
        {
            if (Me.CurrentTarget != null)
                cachedTargetAuras = Me.CurrentTarget.GetAllAuras();
            cachedAuras = Me.GetAllAuras();
        }
        #endregion

        #region Cooldown Checks
        private Dictionary<WoWSpell, long> Cooldowns = new Dictionary<WoWSpell, long>();
        public TimeSpan cooldownLeft(int Spell)
        {
            SpellFindResults Results;
            if (SpellManager.FindSpell(Spell, out Results))
            {
                WoWSpell Result = Results.Override ?? Results.Original;
                if (Cooldowns.TryGetValue(Result, out lastUsed))
                {
                    if (DateTime.Now.Ticks < lastUsed)
                        return Result.CooldownTimeLeft;
                    return TimeSpan.MaxValue;
                }
            }
            return TimeSpan.MaxValue;
        }
        long lastUsed;
        public int lastCast;
        public bool onCooldown(int Spell)
        {
            SpellFindResults Results;
            if (SpellManager.FindSpell(Spell, out Results))
            {
                WoWSpell Result = Results.Override ?? Results.Original;
                if (Cooldowns.TryGetValue(Result, out lastUsed))
                {
                    if (DateTime.Now.Ticks < lastUsed)
                        return Result.Cooldown;
                    return false;
                }
            }
            return false;
        }
        public TimeSpan spellCooldownLeft(int Spell, bool useTracker = false)
        {
            if (useTracker)
                return cooldownLeft(Spell);
            SpellFindResults results;
            if (SpellManager.FindSpell(Spell, out results))
            {
                if (results.Override != null)
                    return results.Override.CooldownTimeLeft;
                return results.Override.CooldownTimeLeft;
            }
            return TimeSpan.MaxValue;
        }
        public bool spellOnCooldown(int Spell, bool useTracker = false)
        {
            if (useTracker)
                return !onCooldown(Spell);
            SpellFindResults results;
            if (SpellManager.FindSpell(Spell, out results))
                return results.Override != null ? results.Override.Cooldown : results.Original.Cooldown;
            return false;
        }
        #endregion

        #region Debuff Checks

        public bool debuffExists(int Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a => a.SpellId == Debuff && a.CreatorGuid == Me.Guid);
                if (aura != null)
                {
                    return true;
                }
            }
            return false;
        }
        public bool debuffExists(string Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a => a.Name == Debuff && a.CreatorGuid == Me.Guid);
                if (aura != null)
                {
                    return true;
                }
            }
            return false;
        }
        public double debuffTimeLeft(int Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a =>
                    a.SpellId == Debuff
                    && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.TimeLeft.TotalMilliseconds;
            }
            return 0;
        }
        public double debuffTimeLeft(string Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a =>
                    a.Name == Debuff
                    && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.TimeLeft.TotalMilliseconds;
            }
            return 0;
        }
        public uint debuffStackCount(int Debuff, WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                WoWAura aura = onTarget.GetAllAuras().FirstOrDefault(a =>
                    a.SpellId == Debuff
                    && a.CreatorGuid == Me.Guid);

                if (aura == null)
                {
                    return 0;
                }
                return aura.StackCount;
            }
            return 0;
        }
        #endregion

        #region Macro Checks
        public bool Manual { get { return Convert.ToBoolean(Lua.GetReturnVal<int>("return Manual and 0 or 1", 0)); } }
        public bool useCDs { get { return Convert.ToBoolean(Lua.GetReturnVal<int>("return useCDs and 0 or 1", 0)); } }
        #endregion

        #region Spell Casting
        private Composite autoAttack()
        {
            return
                new PrioritySelector(
                    new Decorator(ret => !StyxWoW.Me.IsAutoAttacking,
                        new Action(ret =>
                        {
                            Lua.DoString("StartAttack()");
                            return RunStatus.Failure;
                        }))
                    );
        }
        private delegate T Selection<out T>(object Context);
        Composite Cast(int Spell, Selection<bool> reqs = null, Selection<WoWUnit> onTarget = null, bool ignoreCanCast = false)
        {
            return
                new Decorator(ret =>
                {
                    if (reqs != null && !reqs(ret))
                        return false;
                    if (!ignoreCanCast && !SpellManager.CanCast(Spell, onTarget != null ? onTarget(ret) : Me.CurrentTarget))
                        return false;
                    return true;
                },
                            new Action(ret =>
                            {
                                WoWSpell castingSpell = Me.CastingSpell;
                                if (castingSpell != null && castingSpell.Id != Spell)
                                    Lua.DoString("SpellStopCasting()");

                                //Logging.Write(Colors.Yellow, useSpell(Spell));
                                SpellManager.Cast(Spell, (onTarget != null ? onTarget(ret) : null));
                                lastCast = Spell;
                            })
                    );
        }
        Composite dropCast(int Spell, Selection<bool> reqs = null, Selection<WoWUnit> onTarget = null, bool ignoreCanCast = false)
        {
            return
                new Decorator(ret =>
                {
                    if (reqs != null && !reqs(ret))
                        return false;
                    if (!ignoreCanCast && !SpellManager.CanCast(Spell, onTarget != null ? onTarget(ret) : Me.CurrentTarget))
                        return false;
                    return true;
                },
                            new Action(ret =>
                            {
                                WoWSpell castingSpell = Me.CastingSpell;
                                if (castingSpell != null && castingSpell.Id != Spell)
                                    Lua.DoString("SpellStopCasting()");
                                //Logging.Write(Colors.Yellow, useSpell(Spell));
                                SpellManager.Cast(Spell, (onTarget != null ? onTarget(ret) : null));
                                SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                                lastCast = Spell;
                            })
                    );
        }
        #endregion

        #region Target Checks
        internal IEnumerable<WoWUnit> attackableTargets
        {
            get 
            { 
                return ObjectManager.GetObjectsOfType<WoWUnit>(true, false).Where(U => U.Attackable 
                    && U.IsAlive 
                    && U.Guid != Me.Guid 
                    && U.IsHostile 
                    && !U.IsTotem
                    && U.CanSelect 
                    && !U.IsFriendly 
                    && !U.IsDead 
                    && !U.IsNonCombatPet 
                    && !U.IsCritter); 
            }
        }
        public bool gotTarget 
        { 
            get 
            {
                if (Me.GotTarget
                    && Me.CurrentTarget != null
                    && Me.CurrentTarget.Attackable)
                {
                    return true;
                }
                return false;
            } 
        }

        public bool isTargetDummy { get { return Me.CurrentTarget.Name == "Training Dummy" || Me.CurrentTarget.Name == "Raider's Training Dummy"; } }

        internal IEnumerable<WoWUnit> nearbyTargets(WoWPoint fromLocation, double Radius)
        {
            var Hostile = attackableTargets;
            var maxDistance = Radius * Radius;
            return Hostile.Where(x => x.Location.DistanceSqr(fromLocation) < maxDistance);
        }
        public double targetDistance(WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.DistanceSqr;
                if (Results != null)
                    return onTarget.DistanceSqr;
            }
            return 0;
        }
        public double targetHP(WoWUnit onTarget)
        {
            if (onTarget != null)
            {
                var Results = onTarget.HealthPercent;
                if (Results != null)
                    return onTarget.HealthPercent;
            }
            return 0;
        }
        #endregion

        #region Timer Checks
        private int conv_Date2Timestam(DateTime _time)
        {
            var date1 = new DateTime(1970, 1, 1);
            DateTime date2 = _time;
            var ts = new TimeSpan(date2.Ticks - date1.Ticks);
            return (Convert.ToInt32(ts.TotalSeconds));
        }
        private uint current_life;
        private int current_time;
        private ulong guid;
        private uint first_life;
        private uint first_life_max;
        private int first_time;
        public long targetExistence(WoWUnit onTarget)
        {
            if (onTarget == null) return 0;
            if (isTargetDummy) return 9999;
            if (onTarget.CurrentHealth == 0 || onTarget.IsDead || !onTarget.IsValid || !onTarget.IsAlive)
                return 0;
            if (guid != onTarget.Guid)
            {
                guid = onTarget.Guid;
                first_life = onTarget.CurrentHealth;
                first_life_max = onTarget.MaxHealth;
                first_time = conv_Date2Timestam(DateTime.Now);
            }
            current_life = onTarget.CurrentHealth;
            current_time = conv_Date2Timestam(DateTime.Now);
            var time_diff = current_time - first_time;
            var hp_diff = first_life - current_life;
            if (hp_diff > 0)
            {
                var full_time = time_diff * first_life_max / hp_diff;
                var past_first_time = (first_life_max - first_life) * time_diff / hp_diff;
                var calc_time = first_time - past_first_time + full_time - current_time;
                if (calc_time < 1) calc_time = 99;
                var time_to_die = calc_time;
                var fight_length = full_time;
                return time_to_die;
            }
            if (hp_diff < 0)
            {
                guid = onTarget.Guid;
                first_life = onTarget.CurrentHealth;
                first_life_max = onTarget.MaxHealth;
                first_time = conv_Date2Timestam(DateTime.Now);
                return -1;
            }
            if (current_life == first_life_max)
                return 9999;
            return -1;
        }
        #endregion

        #endregion

        #region useaoe
        public bool useAoe
        {
            get
            {
                if (gotTarget)
                {
                    if (stopAoe)
                    {
                        return false;
                    }
                    else if (SpriestSettings.myPrefs.usemindsear == 0)
                    {
                        return false;
                    }
                    else if (addCount >= SpriestSettings.myPrefs.startaoe)
                    {
                        return true;
                    }
                }
                return false;
            }
        }
        #endregion useaoe

        #region flaskbuffs
        public bool FlaskBuff()
        {
            if (Me.HasAura("Flask of the Warm Sun")) { return true; }
            if (Me.HasAura("Flask of Winter's Bite")) { return true; }
            if (Me.HasAura("Flask of the Earth")) { return true; }
            if (Me.HasAura("Flask of Spring Blossoms")) { return true; }
            if (Me.HasAura("Flask of Falling Leaves")) { return true; }
            if (Me.HasAura("Flask of the Winds")) { return true; }
            if (Me.HasAura("Flask of Titanic Strenght")) { return true; }
            if (Me.HasAura("Flask of the Draconic Mind")) { return true; }
            if (Me.HasAura("Flask of Flowing Water")) { return true; }
            if (Me.HasAura("Flask of Steelskin")) { return true; }
            if (Me.HasAura("Flask of Endless Rage")) { return true; }
            if (Me.HasAura("Flask of Pure Mojo")) { return true; }
            if (Me.HasAura("Flask of Stoneblood")) { return true; }
            if (Me.HasAura("Flask of the Frost Wyrm")) { return true; }
            if (Me.HasAura("Flask of Toughness")) { return true; }
            if (Me.HasAura("Flask of Binding Light")) { return true; }
            return false;
        }
        #endregion flaskbuffs

        #region AlchemyFlask
        public void AlchemistFlask()
        {
            if (SpriestSettings.myPrefs.alchemyflask == 1)
            {
                string myAura = "";
                if (Me.Class == WoWClass.Priest
                    || Me.Class == WoWClass.Mage
                    || Me.Class == WoWClass.Warlock
                    || Me.Specialization == WoWSpec.ShamanRestoration
                    || Me.Specialization == WoWSpec.ShamanElemental
                    || Me.Specialization == WoWSpec.PaladinHoly
                    || Me.Specialization == WoWSpec.MonkMistweaver
                    || Me.Specialization == WoWSpec.DruidRestoration
                    || Me.Specialization == WoWSpec.DruidBalance)
                {
                    myAura = "Intellect";
                }
                if (Me.Class == WoWClass.Hunter
                    || Me.Class == WoWClass.Rogue
                    || Me.Specialization == WoWSpec.DruidFeral
                    || Me.Specialization == WoWSpec.MonkWindwalker
                    || Me.Specialization == WoWSpec.MonkBrewmaster
                    || Me.Specialization == WoWSpec.ShamanEnhancement)
                {
                    myAura = "Agility";
                }
                if (Me.Class == WoWClass.Warrior
                    || Me.Class == WoWClass.DeathKnight
                    || Me.Specialization == WoWSpec.PaladinRetribution
                    || Me.Specialization == WoWSpec.PaladinProtection)
                {
                    myAura = "Strenght";
                }

                if (!Me.HasAura("Enhanced " + myAura) && !FlaskBuff() && !Me.Mounted)
                {
                    foreach (WoWItem item in Me.BagItems)
                    { 
                        if (item != null)
                        {
                            if (item.Name == "Alchemist's Flask")
                            {
                                Lua.DoString("RunMacroText(\"/use " + item.Name + "\")");
                                LogMsg("Using Alchemist's Flask", 2);
                                break;
                            }
                        }
                        else
                        {
                            LogMsg("I don't have Alchemy Flask", 2);
                        }
                    }
                }
            }
        }
        #endregion AlchemyFlask
        #region pause

        public bool Paused = false;
        public bool DisableAoe = false;

        public override void ShutDown()
        {
            Lua.Events.DetachEvent("MODIFIER_STATE_CHANGED", HandleModifierStateChanged);
            
        }

        private void HandleModifierStateChanged(object sender, LuaEventArgs args)
        {
            if (SpriestSettings.myPrefs.PauseKeys == SpriestSettings.Keypress.None
                && SpriestSettings.myPrefs.StopAoeKeys == SpriestSettings.Keypress.None)
            {
                return;
            }

            if (Convert.ToInt32(args.Args[1]) == 1)
            {
                if (args.Args[0].ToString() == SpriestSettings.myPrefs.PauseKeys.ToString())
                {
                    Paused = !Paused;
                    if (Paused)
                    {
                        Logging.Write("Spriest PAUSED, press {0} in WOW to continue",
                                     SpriestSettings.myPrefs.PauseKeys.ToString());
                        if (SpriestSettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Spriest PAUSED\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                    else
                    {
                        Logging.Write("Spriest Running....");
                        if (SpriestSettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"spriest Resumed\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                }
            }
            if (Convert.ToInt32(args.Args[1]) == 1)
            {
                if (args.Args[0].ToString() == SpriestSettings.myPrefs.StopAoeKeys.ToString())
                {
                    DisableAoe = !DisableAoe;
                    if (DisableAoe)
                    {
                        Logging.Write("Aoe PAUSED, press {0} in WOW to continue",
                                     SpriestSettings.myPrefs.StopAoeKeys.ToString());
                        if (SpriestSettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Aoe PAUSED\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                    else
                    {
                        Logging.Write("Aoe back on....");
                        if (SpriestSettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Aoe back on\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                }
            }
        }
        #endregion pause
    }
}